/*
 * Copyright (C) 2009 Jiannan Lu
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.restsql.atom.util;

import com.restsql.atom.Content;
import com.restsql.atom.Entry;
import com.sun.net.httpserver.HttpExchange;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.sql.ResultSet;
import com.restsql.atom.Feed;
import com.restsql.atom.Link;
import com.restsql.db.Database;
import com.restsql.http.Parameters;
import java.net.URLEncoder;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import restsql.Main;

/**
 *
 * @author L
 */
public class FeedUtil {

    public FeedUtil() {
    }

    public static String DataToFeed(ResultSet rs, HttpExchange httpExchange, Database db) throws UnsupportedEncodingException, SQLException {

        String rqst_path = //URLDecoder.decode(
                httpExchange.getRequestURI().toString();//, "utf-8");

        int pageIndex = 1;
        int pageSize = 50;
        Boolean isJoinRetrieve = rqst_path.split("\\+?\\/\\+?").length > 2;
        String queries = httpExchange.getRequestURI().getQuery();

        if(queries!=null){
            String[] queries_contents = queries.split("\\&");
            //Boolean is$PageRetrieve = rqst_path.matches("\\$page");
            //Boolean is$PageSizeRetrieve = rqst_path.matches("\\$pagesize");
            for (int i = 0; i < queries_contents.length; i++) {
                String[] quries = queries_contents[i].split("\\=");
                if (queries_contents[i].indexOf("$") > -1) {
                    String element = quries[0];
                    if (element.equals(Parameters.Page)) {
                        pageIndex = Integer.parseInt(quries[1]);
                    } else if (element.equals(Parameters.PageSize)) {
                        pageSize = Integer.parseInt(quries[1]);
                    }
                }
            }
        }
        int upper_limit = pageIndex * pageSize;
        int lower_limit = (pageIndex - 1) * pageSize;

        String rootURL = Main.HOST_URL;
        String URL = rootURL + rqst_path;

        Feed feed = new Feed(URL, rqst_path);

        //feed.setUpdated(new Date());

        List entries = new ArrayList();
        ResultSetMetaData rsmd = rs.getMetaData();
//

        int numberOfColumns = rsmd.getColumnCount();
        String[] ColumnNames = new String[numberOfColumns];
        String[] ColumnTypeNames = new String[numberOfColumns];
        String EntryTitle = "Entry";
        String LinkTblName = "";
        for (int i = 1; i <= numberOfColumns; i++) { 
            ColumnNames[i - 1] = rsmd.getColumnName(i);
            ColumnTypeNames[i - 1] = rsmd.getColumnTypeName(i);
            EntryTitle = rsmd.getTableName(i);
            LinkTblName = rsmd.getTableName(i);
        }
        int entry_count = 1;

        String Entry_id = "";
        while (rs.next()) {
            if (entry_count >= lower_limit && entry_count <= upper_limit) {
                List contents = new ArrayList();
                List links = new ArrayList();
                if (isJoinRetrieve) {
                    EntryTitle = "Entry" + ": " + Integer.toString(entry_count);
                    Entry_id = URL + " :" + entry_count;
                }
                Entry entry = new Entry(Entry_id, EntryTitle);
                StringBuilder value = new StringBuilder();
                Set set = new HashSet();
                String keyStr = "";
                for (int i = 1; i <= numberOfColumns; i++) {
                    if (!isJoinRetrieve && db.getColumnInfo(LinkTblName).isPrimaryKey(ColumnNames[i - 1])) {
                        keyStr = keyStr+rs.getString(i)+",";
                        
                    }
                    if(set.add(ColumnNames[i - 1].toUpperCase()))
                    {
                        value.append("<" + ColumnNames[i - 1] + ">" + rs.getString(i) + "</" + ColumnNames[i - 1] + ">");
                    }
                }
                String SingleRsrcURL;
                if(keyStr.length()!=0){
                    SingleRsrcURL = rootURL + "/" + URLEncoder.encode(LinkTblName + "(" + keyStr.substring(0,keyStr.lastIndexOf(',')) + ")", "utf-8");
                }else{
                    SingleRsrcURL = URL+":"+entry_count;
                }
                entry.setId(SingleRsrcURL);
                entry.setTitle(SingleRsrcURL);
                links.add(new Link("self", "application/atom+xml", SingleRsrcURL));
                links.add(new Link("edit", "application/atom+xml", SingleRsrcURL));
                Content content = new Content();
                content.setValue(value.toString());

                contents.add(content);
                entry.setContents(contents);
                entry.setAlternateLinks(links);
                entries.add(entry);
            }
            entry_count++;
        }

        List feedlinks = new ArrayList();
        String pageURL = URL.indexOf("?")==-1?URL:URL.substring(0, URL.indexOf("?"));
        feedlinks.add(new Link("self", "", pageURL + "?"+"$page=" + pageIndex));
        feedlinks.add(new Link("first", "", pageURL + "?"+"$page=1"));
        int lastpageindex = ((((double)entry_count/(double)pageSize)>(entry_count/pageSize)?entry_count/pageSize+1:entry_count/pageSize));
        feedlinks.add(new Link("next", "", pageURL+ "?"+"$page=" + ((pageIndex*pageSize)>entry_count?lastpageindex:(pageIndex+1))));
        feedlinks.add(new Link("last", "", pageURL+ "?"+"$page="+lastpageindex));//(entry_count/pageSize)));

        feed.setOtherLinks(feedlinks);
        feed.setEntries(entries);
        if (feed.getEntries().size() == 0) {
            return "";
        } else {
            return "<?xml version='1.0' encoding='UTF-8'?>" + feed.toString();
        }

    }
}
